import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from matplotlib import rcParams

def plot_knapsack_results(csv_file):
    # 设置中文字体(尝试多种常见字体)
    try:
        rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'Arial Unicode MS', 'sans-serif']
        rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
    except:
        print("警告: 中文字体设置失败，图表可能无法正常显示中文")
    
    # 读取CSV文件
    data = pd.read_csv(csv_file)
    
    # 创建图表
    plt.figure(figsize=(16, 12))
    plt.suptitle('背包问题算法性能对比 (实际执行时间 vs 理论时间复杂度)', fontsize=16, y=1.02)
    
    # 创建子图1: 执行时间对比
    plt.subplot(2, 1, 1)
    
    # 绘制各算法时间曲线(按不同容量分组)
    capacities = data['背包容量'].unique()
    algorithms = ['蛮力法时间(ms)', '动态规划时间(ms)', '贪心法时间(ms)', '回溯法时间(ms)']
    labels = ['蛮力法', '动态规划', '贪心法', '回溯法']
    colors = ['red', 'blue', 'green', 'purple']
    markers = ['o', 's', '^', 'D']
    
    for cap in capacities:
        cap_data = data[data['背包容量'] == cap]
        for algo, label, color, marker in zip(algorithms, labels, colors, markers):
            y_values = np.where(cap_data[algo] > 0, cap_data[algo]/1000, None)
            plt.plot(cap_data['物品数量'], y_values,
                    label=f'{label}(容量={cap})',
                    color=color, marker=marker, linestyle='--')
    
    # 添加理论时间复杂度曲线
    x = np.array(data['物品数量'])
    plt.plot(x, 0.000001 * (2**x), 'k:', label='蛮力法理论O(2^n)')
    plt.plot(x, 0.0001 * x * capacities[0], 'k--', label='动态规划理论O(nW)')
    plt.plot(x, 0.00001 * x * np.log(x), 'k-.', label='贪心法理论O(n log n)')
    
    plt.xlabel('物品数量', fontsize=12)
    plt.ylabel('执行时间(秒)', fontsize=12)
    plt.title('执行时间对比 (实际 vs 理论)', fontsize=14)
    plt.legend(fontsize=8, bbox_to_anchor=(1.05, 1), loc='upper left')
    plt.grid(True, linestyle='--', alpha=0.7)
    plt.yscale('log')  # 使用对数坐标更清晰展示指数级增长
    
    # 创建子图2: 内存使用对比
    plt.subplot(2, 1, 2)
    for cap in capacities:
        cap_data = data[data['背包容量'] == cap]
        y_values = np.where(cap_data['动态规划内存(MB)'] > 0,
                           cap_data['动态规划内存(MB)'], None)
        plt.plot(cap_data['物品数量'], y_values,
                label=f'动态规划内存(容量={cap})',
                color='blue', marker='o', linestyle='-')
    
    plt.xlabel('物品数量', fontsize=12)
    plt.ylabel('内存使用(MB)', fontsize=12)
    plt.title('动态规划内存使用 (理论O(W))', fontsize=14)
    plt.legend(fontsize=8)
    plt.grid(True, linestyle='--', alpha=0.7)
    plt.yscale('log')  # 使用对数坐标
    
    plt.tight_layout()
    
    # 保存图片
    output_file = csv_file.replace('.csv', '_performance.png')
    plt.savefig(output_file, dpi=300, bbox_inches='tight')
    plt.close()
    print(f"图表已保存为: {output_file}")

if __name__ == "__main__":
    import sys
    if len(sys.argv) > 1:
        plot_knapsack_results(sys.argv[1])
    else:
        plot_knapsack_results('knapsack_results.csv')

if __name__ == "__main__":
    import sys
    if len(sys.argv) > 1:
        plot_knapsack_results(sys.argv[1])
    else:
        plot_knapsack_results('knapsack_results.csv')